package br.ufrj.dcc.so;

import java.util.concurrent.Semaphore;

import br.ufrj.dcc.so.entidades.barbeiros.BarbeiroAbstrato;
import br.ufrj.dcc.so.entidades.barbeiros.BarbeiroOficial;
import br.ufrj.dcc.so.entidades.barbeiros.BarbeiroPraca;
import br.ufrj.dcc.so.entidades.barbeiros.BarbeiroSargento;
import br.ufrj.dcc.so.entidades.militares.SargentoTainha;
import br.ufrj.dcc.so.entidades.militares.TenenteEscovinha;
import br.ufrj.dcc.so.forte.Forte;
import br.ufrj.dcc.so.forte.ForteThome;
import br.ufrj.dcc.so.forte.GeradorEventosImpl;
import br.ufrj.dcc.so.forte.barbearia.Barbearia;
import br.ufrj.dcc.so.forte.barbearia.BarbeariaRecrutaZero;

public class Trab2SO {

	/**
	 * Indica quantos produtos podem ser produzidos antes que sejam consumidos.
	 */
	private static final int NUM_LUGARES = 20;
	
	/**
	 * Indica quantos produtos estarão produzidos no início da execução.
	 */
	private static int NUM_PRODUZIDOS = 0;
	
	/**
	 * O primeiro a tentar fazer uso da exclusão mútua vai encontrar o caminho liberado
	 */
	private static int CAMINHO_LIVRE = 1;
	
	public static void main(String[] args) {

		Semaphore semaforoClientes = new Semaphore(NUM_PRODUZIDOS, true);
		Semaphore semaforoLugares = new Semaphore(NUM_LUGARES, true);
		Semaphore semaforoOficial = new Semaphore(CAMINHO_LIVRE, true);
		Semaphore semaforoSargento = new Semaphore(CAMINHO_LIVRE, true);
		Semaphore semaforoPraca = new Semaphore(CAMINHO_LIVRE, true);
		
				
		Barbearia barbearia = new BarbeariaRecrutaZero(semaforoOficial, semaforoSargento, semaforoPraca);
		new Thread(barbearia).start();
		
		BarbeiroAbstrato barbeiroOficial = new BarbeiroOficial(barbearia, semaforoLugares, semaforoClientes);
		BarbeiroAbstrato barbeiroPraca = new BarbeiroPraca(barbearia, semaforoLugares, semaforoClientes);
		BarbeiroAbstrato barbeiroSargento = new BarbeiroSargento(barbearia, semaforoLugares, semaforoClientes);
		
		Forte forte = new ForteThome(new GeradorEventosImpl());
		
		SargentoTainha tainha = new SargentoTainha(forte, barbearia, semaforoLugares, semaforoClientes);
		
		TenenteEscovinha escovinha = new TenenteEscovinha(barbearia);
		
		barbearia.addFuncionario(barbeiroOficial, barbeiroPraca, barbeiroSargento, tainha, escovinha);
		
		new Thread(barbeiroOficial).start();
		new Thread(barbeiroPraca).start();
		new Thread(barbeiroSargento).start();
		new Thread(tainha).start();
		new Thread(escovinha).start();
		
	}

}
